import { FrameType } from "./type";
import util from "./util";

export default class Player {
    _numPlays = 0;
    _ended = false;
    _paused = true;
    _currentFrameNumber = 0;
    _endFrameNumber = 0;
    /** @type {APNG} */
    _apng: FrameType;
    playbackRate = 1;
    _loop = false;
    imgRef: HTMLImageElement;
    endFrame: number;
    startFrame: number;
    startLoopPlay?: () => void;
    endLoopPlay?: () => void;
    constructor(apng, autoPlay = false, imgRef, startFrame?, endFrame?, startLoopPlay?, endLoopPlay?) {
        this._apng = apng;
        this.imgRef = imgRef;
        this._currentFrameNumber = startFrame || 0;
        this.startFrame = startFrame || 0;
        this.endFrame = endFrame || apng.frames.length - 1;
        if (this.endFrame > apng.frames.length - 1) {
            this.endFrame
        }
        this.startLoopPlay = startLoopPlay;
        this.endLoopPlay = endLoopPlay;
        // this.stop();

        if (autoPlay) {
            this.play();
        }
    }

    get currentFrame() {
        return this._apng.frames[this._currentFrameNumber];
    }

    renderNextFrame() {
        this._currentFrameNumber++;

        // 如果有结束帧，那么看是否有循环，没有的话直接结束
        if (this._currentFrameNumber > this.endFrame) {
            this.endLoopPlay && this.endLoopPlay();

            if (this._loop) {
                this._currentFrameNumber = this.startFrame;
            } else {
                this._ended = true;
                return;
            }
        }

        const frame = this.currentFrame.frame;
        this.imgRef.src = frame;
        // console.log(this._currentFrameNumber, 'ddd', this.startFrame);

        // 如果是初始帧
        if (this._currentFrameNumber === this.startFrame) {
            this.startLoopPlay && this.startLoopPlay();
        }
    }

    play() {
        if (this._ended) {
            this.stop();
        }
        this._paused = false;

        let nextRenderTime = performance.now() + this.currentFrame.delay / this.playbackRate;
        const tick = now => {


            if (this._ended) {
                util.off("loop", tick);
                return;
            }
            if (now >= nextRenderTime) {
                do {
                    nextRenderTime += this.currentFrame.delay / this.playbackRate;
                    if (!this._paused) {
                        this.renderNextFrame();
                    }
                } while (!this._ended && now > nextRenderTime);
            }
            // requestAnimationFrame(tick);
        };

        util.on("loop", tick);
        // requestAnimationFrame(tick);
    }

    initPlay() {
        this.stop();
        this.play();
    }

    switchPauseStart() {
        this._paused = !this._paused;
    }


    stop() {
        this._numPlays = 0;
        this._ended = false;
        this._paused = true;
        // render first frame
        this._currentFrameNumber = this.startFrame - 1;
        this.renderNextFrame();
    }
}